package com.atguigu.gmall.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {


    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${authUrls.url}")
    private String authUrls;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String path = request.getURI().getPath();
        if(antPathMatcher.match("/**/inner/**", path)){
            return out(response,ResultCodeEnum.PERMISSION);
        }
        //获取当前用户ID
        String userId = getUserId(request);
        if(antPathMatcher.match("/api/**/auth/**",path)){
            if(null == userId){
                return out(response,ResultCodeEnum.LOGIN_AUTH);
            }
        }
        //判断是否跳转页面
        for (String url : authUrls.split(",")) {
            if(path.indexOf(url) != -1 && StringUtils.isEmpty(userId)){
                //未登录  跳转登录页面
                response.setStatusCode(HttpStatus.SEE_OTHER);
                response.getHeaders().set(HttpHeaders.LOCATION,
                        "http://passport.gmall.com/login.html?originUrl="
                                + request.getURI().getRawSchemeSpecificPart());
                return response.setComplete();
            }
        }
        //判断是否为空
        if(!StringUtils.isEmpty(userId)){
            request.mutate().header("userId",userId);
        }
        String userTempId = getUserTempId(request);
        if(!StringUtils.isEmpty(userTempId)){
            request.mutate().header("userTempId",userTempId);
        }
        return chain.filter(exchange);
    }

    private String getUserTempId(ServerHttpRequest request){
        String userTempId = request.getHeaders().getFirst("userTempId");
       if(null != userTempId){
           return userTempId;
       }
        HttpCookie httpCookie = request.getCookies().getFirst("userTempId");
       if(null != httpCookie){
           return  httpCookie.getValue();
       }
       return null;
    }

    private String getUserId(ServerHttpRequest request){
        String token = request.getHeaders().getFirst("token");//token
        if(null == token){
            HttpCookie httpCookie = request.getCookies().getFirst("token");
            if(null != httpCookie){
                token =  httpCookie.getValue();
            }
        }
        if(null != token){
            String key = "user:login:" +  token;
            System.out.println(key);
            if(redisTemplate.hasKey(key)){
                return (String) redisTemplate.opsForValue().get(key);
            }
        }
        return null;
    }

    private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {
        Result result = Result.build(null,resultCodeEnum);
        byte[] bytes = JSON.toJSONString(result).getBytes();
        DataBuffer wrap = response.bufferFactory().wrap(bytes);
        response.getHeaders().set(HttpHeaders.CONTENT_TYPE,"application/json;charset=utf-8");
        return response.writeWith(Mono.just(wrap));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
